package com.practicesuite.systemlayer;

import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Invoice Class
 * @author Ronald Bron
 * Georgia Institute of Technology, 2011 2340
 */
public class Invoice implements Serializable {
    private Patient patient;
    private Date date;
    private Map<Double,String> services;
    private Map<Double,String> discounts;
    private double totalSavings = 0;
    private double totalCosts = 0;
    private int invoiceNumber = 0 ;
    private String docName = "";
    private int treatmentRecId = 0;

    /**
     * Constructor
     * @param patientName Name of Patient
     * @param date Date of Service
     * @param services Dictionary of services and costs
     * @param discounts Dictionary of discounts and reasons
     */
    public Invoice(Patient patient, Date date,
            Map<Double, String> services,
            Map<Double, String> discounts, int invoiceNumber, String docName, int treatmentRecId) {
        this.patient = patient;
        this.date = date;
        this.services = services;
        this.discounts = discounts;
        this.invoiceNumber = invoiceNumber;
        this.docName = docName;
        this.treatmentRecId = treatmentRecId;
    }
    
    /**
     * Private method to generate header
     * @return Returns header for Invoice
     */
    private String generateHeader() {
        Date d = new Date();
        String result = "";
        result = "Under the C Invoice Statement \n" + 
                  "Name: " + this.patient.getName() + "\n" + 
                  "Printed: " + d.toString() + "\n" +
                  //TODO: There will be a system call to generate invoice number here
                  "Invoice Number: " + this.invoiceNumber + "\n"; 
                  
        return result;
    }
    
    /**
     * Private method to generate the main data for the form
     * @return
     */
    private String generateData() {
        Date d = new Date();
        StringBuilder sb = new StringBuilder();
        sb.append("Date \t \t \t \tDescription \t Cost\t \t \t \n");
        sb.append("------------------------------------------------------------\n");
        for(Entry<Double, String> s : this.services.entrySet()) {
            sb.append(d.toString() + "\t" + s.getValue() + "\t$" + s.getKey() + "\n");
            this.totalCosts+= s.getKey();
        }
        sb.append("------------------------------------------------------------\n");
        return sb.toString();
    }
    
    /**
     * Private method to generate the discounts portion of the form
     * @return
     */
    private String generateDiscounts() {
        StringBuilder sb = new StringBuilder();
        sb.append("Discounts\n" + 
                "------------------------------------------------------------\n" + 
                   "Reason: \t\t Amount: \n");
        for(Entry<Double, String> s : this.discounts.entrySet()) {
            sb.append(s.getValue() + "\t$" + s.getKey() + "\n");
            this.totalSavings+= s.getKey();
        }
        sb.append("------------------------------------------------------------\n");
        sb.append("Total Savings: $" + this.totalSavings + "\n");
    return sb.toString();
    }
    
    /**
     * Returns invoice in nice, readable format
     */
    public String toString() {
        double finalCost = 0;
        StringBuilder sb = new StringBuilder();
        sb.append(this.generateHeader());
        sb.append(this.generateData());
        sb.append(this.generateDiscounts());
        
        if(this.totalCosts == 0) {
            finalCost = 0;
        }
        else if(this.totalCosts > this.totalCosts) {
            finalCost = 0;
        }
        else {
            finalCost = this.totalCosts - this.totalSavings;
        }
        sb.append("Final Total: $" + finalCost + "\n");
        sb.append("Doctor Seen: " + getDocName() + "\n");
        
        
        return sb.toString();
    }

    public String getDocName() {
        return docName;
    }

    public void setDocName(String docName) {
        this.docName = docName;
    }

    public Patient getPatient() {
        return patient;
    }

    public void setPatient(Patient patient) {
        this.patient = patient;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public Map<Double, String> getServices() {
        return services;
    }

    public void setServices(Map<Double, String> services) {
        this.services = services;
    }

    public Map<Double, String> getDiscounts() {
        return discounts;
    }

    public void setDiscounts(Map<Double, String> discounts) {
        this.discounts = discounts;
    }

    public double getTotalSavings() {
        return totalSavings;
    }

    public void setTotalSavings(double totalSavings) {
        this.totalSavings = totalSavings;
    }

    public double getTotalCosts() {
        return totalCosts;
    }

    public void setTotalCosts(double totalCosts) {
        this.totalCosts = totalCosts;
    }
    
    
    public int getInvoiceNumber() {
        return invoiceNumber;
    }

    public void setInvoiceNumber(int invoiceNumber) {
        this.invoiceNumber = invoiceNumber;
    }    


    

}
